package com.elinshaw.pattern.observer;

/**
 * 观察者线程
 * 对线程中的任务执行添加观察能力并获得最后计算结果
 *
 * @author elinShaw
 */
public class ObserverThread<T> extends Thread implements Observer {

    private final TaskLifeCycle<T> taskLifeCycle;

    private final Task<T> task;

    private Cycle cycle;

    public ObserverThread(Task<T> task) {
        this(new EmptyLifeCycle<T>(), task);
    }

    public ObserverThread(TaskLifeCycle<T> taskLifeCycle, Task<T> task) {
        super();
        if (task == null) {
            throw new IllegalArgumentException("The task is required");
        }
        this.taskLifeCycle = taskLifeCycle;
        this.task = task;
    }

    /**
     * 事件源发起者
     */
    @Override
    public final void run() {
        //执行线程逻辑单元分别触发相应事件
        this.update(Cycle.STARTED, null, null);
        try {
            this.update(Cycle.RUNNING, null, null);
            T result = this.task.call();
            this.update(Cycle.DONE, result, null);
        } catch (Exception e) {
            this.update(Cycle.ERROR, null, e);
        }
    }


    private void update(Cycle cycle, T result, Exception e) {
        this.cycle = cycle;
        if (taskLifeCycle == null) {
            return;
        }
        switch (cycle) {
            case STARTED:
                this.taskLifeCycle.onStart(currentThread());
                break;
            case RUNNING:
                this.taskLifeCycle.onRunning(currentThread());
                break;
            case DONE:
                this.taskLifeCycle.onFinish(currentThread(), result);
                break;
            case ERROR:
                this.taskLifeCycle.onError(currentThread(), e);
                break;
        }
    }

    @Override
    public Cycle getCycle() {
        return this.cycle;
    }
}
